home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / allowo1g / domtree.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-08-27  |  17.6 KB  |  442 lines

  1. VERSION 5.00
  2. Object = "{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}#1.1#0"; "SHDOCVW.DLL"
  3. Begin VB.Form frmDOMTree 
  4.    BackColor       =   &H00FFFFFF&
  5.    Caption         =   "DOM Tree"
  6.    ClientHeight    =   4395
  7.    ClientLeft      =   60
  8.    ClientTop       =   630
  9.    ClientWidth     =   5880
  10.    LinkTopic       =   "Form1"
  11.    MDIChild        =   -1  'True
  12.    ScaleHeight     =   4395
  13.    ScaleWidth      =   5880
  14.    WindowState     =   2  'Maximized
  15.    Begin SHDocVwCtl.WebBrowser wbr 
  16.       Height          =   2235
  17.       Left            =   720
  18.       TabIndex        =   0
  19.       Top             =   840
  20.       Width           =   4515
  21.       ExtentX         =   7964
  22.       ExtentY         =   3942
  23.       ViewMode        =   0
  24.       Offline         =   0
  25.       Silent          =   0
  26.       RegisterAsBrowser=   0
  27.       RegisterAsDropTarget=   1
  28.       AutoArrange     =   0   'False
  29.       NoClientEdge    =   0   'False
  30.       AlignLeft       =   0   'False
  31.       ViewID          =   "{0057D0E0-3573-11CF-AE69-08002B2E1262}"
  32.       Location        =   ""
  33.    End
  34.    Begin VB.Menu mnuFileMenu 
  35.       Caption         =   "&File"
  36.       Index           =   0
  37.       Begin VB.Menu mnuFile 
  38.          Caption         =   "&HTML"
  39.          Index           =   0
  40.       End
  41.       Begin VB.Menu mnuFile 
  42.          Caption         =   "-"
  43.          Index           =   1
  44.       End
  45.       Begin VB.Menu mnuFile 
  46.          Caption         =   "&Close"
  47.          Index           =   2
  48.       End
  49.    End
  50. Attribute VB_Name = "frmDOMTree"
  51. Attribute VB_GlobalNameSpace = False
  52. Attribute VB_Creatable = False
  53. Attribute VB_PredeclaredId = True
  54. Attribute VB_Exposed = False
  55. Option Explicit
  56. ' DOMTree.frm   July 1999  contact markb@orionstudios.com
  57. ' Demonstrates DOM programming from Vb6 including
  58. '   recursive traversal of an HTML document structure   (see RecurseDOMTree)
  59. '   extracting stylesheet information from a document   (see DisplayStyleSheets)
  60. '   constructing an expand/collapse UL object and inserting it into a document
  61. '   cloning a structure (see CreatePropsClone, CreateInfoSpan)
  62. '   intercepting click events from WebBrowser document  (see mProps, mExpand)
  63. '   behavior (DOMTree.htc) attached to DIV (MainDIV) via CSS class (DOMTree.css)
  64. ' Requires Project/References entry for
  65. '   Microsoft HTML Object Library (MSHTML.tlb)
  66. '====================================================================================
  67. ' Enumerations
  68. Public Enum DOMInfoType ' determines which display is built - see DisplayDOMInfo
  69.     domiTree    ' Document Tree
  70.     domiStyle   ' Style Specs
  71. End Enum
  72. ' Module-level Object variables
  73. Private mvarMDIParent As MDIForm    ' useful to access parent form - see StatusText
  74. Private mDOMDoc As MSHTML.HTMLDocument  ' document to be analysed - see DisplayDOMInfo
  75. Private mWbrDoc As MSHTML.HTMLDocument  ' document in WebBrowser (HTML_TEMPLATE)
  76. Private mWbrDocWin As MSHTML.HTMLWindow2    ' window containing WebBrowser document
  77. Attribute mWbrDocWin.VB_VarHelpID = -1
  78. Private mULRoot As MSHTML.HTMLUListElement      ' top-level UL added to WebBrowser document
  79. Private mCloneSPAN As MSHTML.HTMLSpanElement    ' see CreatePropsClone
  80. ' Objects in WebBrowser document HTML_TEMPLATE
  81. Private mProgressNodes As MSHTML.IHTMLDOMTextNode   ' progress display
  82. Private WithEvents mProps As MSHTML.HTMLTableCell   ' toggles properties display
  83. Attribute mProps.VB_VarHelpID = -1
  84. Private WithEvents mExpand As MSHTML.HTMLTableCell  ' expands/collapses tree display
  85. Attribute mExpand.VB_VarHelpID = -1
  86. ' Miscellaneous module-level variables
  87. Private mDefaultPath As String      ' assigned in Form_Initialize
  88. Private mDOMInfoType As DOMInfoType ' indicates which display is built
  89. Private mDOMInfoCaption As Variant  ' array of caption strings
  90. Private mNodeCount As Long          ' compared with PROGRESS_INTERVAL
  91. ' Module-level Constants
  92. Private Const PROGRESS_INTERVAL As Long = 20    ' see AddLInode_Exit
  93. Private Const HTML_TEMPLATE = "DOMTree.htm"     ' template for building display
  94. Private Const CL_INFOSPAN = "infoSPAN"
  95. Private Const CL_PARENT = "clParent"
  96. Private Const CL_CHILD = "clChild"
  97. Private Const WORKING = " Working ..."
  98. Private Const READY = " Ready"
  99. ' Relevant nodeType constants
  100. Private Const ELEMENT_NODE = 1
  101. Private Const TEXT_NODE = 3
  102. ' Browser navigation constants
  103. Private Const navNoHistory = 2
  104. ' File Menu Constants
  105. Private Const FILE_HTML = 0
  106. Private Const FILE_CLOSE = 2
  107. Public Property Set MDIParent(vData As MDIForm) ' optional
  108.    Set mvarMDIParent = vData
  109. End Property
  110. Private Property Let StatusText(ByVal vData As String)
  111.     On Error Resume Next
  112.     If Not (mvarMDIParent Is Nothing) Then  ' property spec is optional
  113.         mvarMDIParent.StatusText = vData
  114.     End If
  115. End Property
  116. Public Sub DisplayDOMInfo( _
  117.             HTMLDoc As MSHTML.HTMLDocument, _
  118.             InfoType As DOMInfoType)
  119.             
  120.     Set mDOMDoc = HTMLDoc   ' retain as module-level variable
  121.     mDOMInfoType = InfoType ' retain as module-level variable
  122.     Me.Caption = mDOMInfoCaption(mDOMInfoType)
  123. ' Processing is triggered when HTML_TEMPLATE is loaded (see wbr_DocumentComplete)
  124.     wbr.Navigate URL:=mDefaultPath & HTML_TEMPLATE, Flags:=navNoHistory
  125. End Sub
  126. Private Sub Form_Initialize()
  127.     mDefaultPath = App.Path & "\"
  128.     mDOMInfoCaption = Array("Document Tree", "Style Specs")
  129.     mDOMInfoType = domiTree  ' default DOMDocInfo property
  130. End Sub
  131. Private Sub Form_Load()
  132.     StatusText = WORKING
  133.     wbr.Navigate "about:<BODY style='overflow:auto'></BODY>", Flags:=navNoHistory
  134. End Sub
  135. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  136.     Me.Visible = False  ' An attempt to speed up closing the form because
  137.     DoEvents            '   displosing of the document may take a while.
  138. End Sub
  139. Private Sub Form_Resize()
  140.     On Error Resume Next
  141.     wbr.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
  142. End Sub
  143. Private Sub mnuFile_Click(Index As Integer)
  144.     On Error Resume Next
  145.     Select Case Index
  146.         Case FILE_HTML
  147.         
  148.             With New frmDOMHTML
  149.                 .Show
  150.                 .DisplayHTML HTMLDoc:=wbr.Document
  151.             End With
  152.             
  153.         Case FILE_CLOSE
  154.         
  155.             Unload Me
  156.             
  157.     End Select
  158. End Sub
  159. Private Sub wbr_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  160.     If pDisp Is wbr.object Then
  161.         If InStr(1, URL, HTML_TEMPLATE, vbTextCompare) Then
  162.             Set mWbrDoc = wbr.Document  ' typecast for early binding
  163.             With mWbrDoc
  164.                 Set mWbrDocWin = .parentWindow
  165.                 Set mProgressNodes = .getElementById("idRow").firstChild
  166.                 .getElementById("idHdr").firstChild.nodeValue = mDOMInfoCaption(mDOMInfoType)
  167.             End With
  168.             DoEvents
  169.             Select Case mDOMInfoType
  170.                 Case domiTree
  171.                     RecurseDOMTree StartFromNode:=mDOMDoc.getElementsByTagName("HTML")(0)
  172.                 Case domiStyle
  173.                     DisplayStyleSheets HTMLDoc:=mDOMDoc
  174.             End Select
  175.             StatusText = READY
  176.         End If
  177.     End If
  178. End Sub
  179. Private Function mProps_onclick() As Boolean    ' Event generated in HTML_TEMPLATE
  180.     Dim blnShow As Boolean
  181.     StatusText = WORKING
  182.     mWbrDocWin.Event.cancelBubble = True
  183.     blnShow = InStr(1, mProps.firstChild.nodeValue, "Show", vbTextCompare)
  184.     PropsToggle ShowAll:=blnShow
  185.     mProps.firstChild.nodeValue = IIf(blnShow, "Hide", "Show") & " properties"
  186.     StatusText = READY
  187. End Function
  188. Private Function mExpand_onclick() As Boolean   ' Event generated in HTML_TEMPLATE
  189.     Dim blnExpand As Boolean
  190.     StatusText = WORKING
  191.     mWbrDocWin.Event.cancelBubble = True
  192.     blnExpand = InStr(1, mExpand.firstChild.nodeValue, "Expand", vbTextCompare)
  193.     ExpandToggle ExpandAll:=blnExpand
  194.     mExpand.firstChild.nodeValue = IIf(blnExpand, "Collapse", "Expand") & " all"
  195.     StatusText = READY
  196. End Function
  197. Private Sub RecurseDOMTree(StartFromNode As MSHTML.IHTMLDOMNode)
  198.     On Error GoTo RecurseDOMTree_Error
  199. ' Initialise a node for cloning (see notes in CreatePropsClone)
  200.     Set mCloneSPAN = CreatePropsClone(HTMLDoc:=mWbrDoc)
  201. ' Create RootNode (fully constructed before added to HTML_TEMPLATE in WebBrowser)
  202.     Set mULRoot = mWbrDoc.createElement("UL")
  203. ' Initiate Recursion
  204.     If StartFromNode.hasChildNodes Then
  205.         ForEachChild FromNode:=StartFromNode, ULParent:=mULRoot
  206.     End If
  207. ' Insert the UL Object into the document (in place of 'Working...')
  208.     With mWbrDoc.getElementById("MainDIV")
  209.         .replaceChild newChild:=mULRoot, oldChild:=.firstChild
  210.     End With
  211. ' Make clickable options available and monitor using 'WithEvents' variable
  212.     With mWbrDoc
  213.         Set mProps = .getElementById("idProps")     ' see mProps_onclick
  214.         Set mExpand = .getElementById("idExpand")   ' see mExpand_onclick
  215.     End With
  216.     mProps.runtimeStyle.visibility = "visible"
  217.     mExpand.runtimeStyle.visibility = "visible"
  218. RecurseDOMTree_Exit:
  219.     Exit Sub
  220. RecurseDOMTree_Error:
  221.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "RecurseDOMTree"
  222.     Resume RecurseDOMTree_Exit
  223. End Sub
  224. Private Sub ForEachChild( _
  225.             FromNode As MSHTML.IHTMLDOMNode, _
  226.             ULParent As MSHTML.HTMLUListElement) ' RECURSIVE
  227.             
  228.     On Error GoTo ForEachChild_Error
  229.     Dim oLI As MSHTML.HTMLLIElement
  230.     Dim oULchild As MSHTML.HTMLUListElement
  231.     Dim oNode As MSHTML.IHTMLDOMNode
  232.     Set oNode = FromNode.firstChild
  233.     Do Until oNode Is Nothing
  234.         Set oLI = AddLInode(oNode, ULParent)
  235.         If oNode.hasChildNodes Then
  236.             oLI.className = CL_PARENT   ' and create new UL for these children
  237.             Set oULchild = ULParent.appendChild(mWbrDoc.createElement("UL"))
  238.             oULchild.className = CL_CHILD
  239.             ForEachChild FromNode:=oNode, ULParent:=oULchild ' RECURSIVE CALL
  240.         End If
  241.         Set oNode = oNode.nextSibling
  242.    Loop
  243. ForEachChild_Exit:
  244.     Exit Sub
  245. ForEachChild_Error:
  246.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "ForEachChild"
  247.     Resume ForEachChild_Exit
  248. End Sub
  249. Private Function AddLInode( _
  250.             N As MSHTML.IHTMLDOMNode, _
  251.             ULParent As MSHTML.IHTMLDOMNode) As MSHTML.HTMLLIElement
  252.             
  253.     On Error GoTo AddLInode_Error
  254.     Dim oLI As MSHTML.HTMLLIElement
  255.     Dim IsText As Boolean
  256.     Dim strCaption As String
  257.     With N
  258.         IsText = .nodeType = TEXT_NODE
  259.         If IsText Then
  260.             strCaption = .nodeValue
  261.         Else
  262.             strCaption = .nodeName
  263.         End If
  264.     End With
  265.     Set oLI = ULParent.appendChild(mWbrDoc.createElement("LI"))
  266.     With oLI
  267.         .appendChild mWbrDoc.createTextNode(strCaption)
  268.         If Not IsText Then
  269.             .appendChild CreateInfoSpan(N)
  270.         End If
  271.     End With
  272.     Set AddLInode = oLI
  273. AddLInode_Exit:
  274.     mNodeCount = mNodeCount + 1
  275.     If mNodeCount Mod PROGRESS_INTERVAL = 0 Then    ' refresh progress display
  276.         mProgressNodes.Data = mNodeCount
  277.         DoEvents
  278.     End If
  279.     Exit Function
  280. AddLInode_Error:
  281.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "AddLInode"
  282.     Resume AddLInode_Exit
  283. End Function
  284. Private Function CreateInfoSpan(DOMNode As MSHTML.IHTMLDOMNode) As MSHTML.HTMLSpanElement
  285.     On Error GoTo CreateInfoSpan_Error
  286.     Dim oSPAN As MSHTML.HTMLSpanElement
  287.     Dim oID As MSHTML.HTMLSpanElement
  288.     Dim oMSHTMLType As MSHTML.HTMLSpanElement
  289.     Dim strID As String
  290.     Dim strClassName As String
  291. ' Clone a new info object (see CreatePropsClone)
  292.     Set oSPAN = mCloneSPAN.cloneNode(True)  ' see CreatePropsClone - only 2 childNodes
  293.     Set oID = oSPAN.firstChild              ' <== use index if more than 2 SPANs are
  294.     Set oMSHTMLType = oSPAN.lastChild       ' <== included in the cloned object
  295. ' ID - defined on document, or allocated by system as 'uniqueID'
  296.     With DOMNode
  297.         If Len(.id) Then
  298.             strID = .id
  299.             strClassName = "idSPAN"
  300.         Else
  301.             strID = .uniqueID
  302.             strClassName = "uniqueIdSPAN"
  303.         End If
  304.     End With
  305.     With oID
  306.         .className = strClassName
  307.         .firstChild.nodeValue = strID
  308.     End With
  309. ' MSHTML Library Type
  310.     oMSHTMLType.firstChild.nodeValue = TypeName(DOMNode)
  311. CreateInfoSpan_Exit:
  312.     Set CreateInfoSpan = oSPAN
  313.     Exit Function
  314. CreateInfoSpan_Error:
  315.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "CreateInfoSpan"
  316.     Resume CreateInfoSpan_Exit
  317. End Function
  318. Private Function PropsToggle(ShowAll As Boolean) As Long
  319.     On Error GoTo PropsToggle_Error
  320.     Dim Result As Long ' default function result is 0 (= False)
  321.     Dim oSPANcollection As MSHTML.IHTMLElementCollection
  322.     Dim strVisibility As String
  323.     Dim IX As Long, IXmax As Long
  324.     strVisibility = IIf(ShowAll, "visible", "hidden")
  325.     Set oSPANcollection = mULRoot.getElementsByTagName("SPAN")
  326.     IXmax = oSPANcollection.length - 1
  327.     For IX = 0 To IXmax
  328.         With oSPANcollection(IX) ' an HTMLSpanElement object
  329.             If .className = CL_INFOSPAN Then
  330.                 .runtimeStyle.visibility = strVisibility
  331.             End If
  332.         End With
  333.     Next IX
  334.     Result = IXmax + 1  ' returns number of elements toggled
  335. PropsToggle_Exit:
  336.     PropsToggle = Result
  337.     Exit Function
  338. PropsToggle_Error:
  339.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "PropsToggle"
  340.     Resume PropsToggle_Exit
  341. End Function
  342. Private Function ExpandToggle(ExpandAll As Boolean) As Long
  343.     On Error GoTo ExpandToggle_Error
  344.     Dim Result As Long ' default function result is 0 (= False)
  345.     Dim oULcollection As MSHTML.IHTMLElementCollection
  346.     Dim strDisplay As String
  347.     Dim IX As Long, IXmax As Long
  348.     strDisplay = IIf(ExpandAll, "block", "")
  349.     Set oULcollection = mULRoot.getElementsByTagName("UL")
  350.     IXmax = oULcollection.length - 1
  351.     For IX = 0 To IXmax
  352.         With oULcollection(IX) ' an HTMLUListElement object
  353.             If .className = CL_CHILD Then
  354.                 .runtimeStyle.display = strDisplay
  355.             End If
  356.         End With
  357.     Next IX
  358.     Result = IXmax + 1  ' returns number of elements toggled
  359. ExpandToggle_Exit:
  360.     ExpandToggle = Result
  361.     Exit Function
  362. ExpandToggle_Error:
  363.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "ExpandToggle"
  364.     Resume ExpandToggle_Exit
  365. End Function
  366. Private Function CreatePropsClone(HTMLDoc As MSHTML.HTMLDocument) As MSHTML.HTMLSpanElement
  367. ' The object created here is cloned to display node properties
  368. '   SPAN (class=infoSPAN)
  369. '       SPAN (class=idSPAN)
  370. '           #text
  371. '       SPAN (class=mshtmlSPAN)
  372. '           #text
  373.     On Error GoTo CreatePropsClone_Error
  374.     Dim Result As MSHTML.HTMLSpanElement    ' default function result is Nothing
  375.     Dim oParent As MSHTML.HTMLSpanElement
  376.     Dim oChild As MSHTML.HTMLSpanElement
  377.     With HTMLDoc
  378.         Set oParent = .createElement("SPAN")
  379.         Set oChild = .createElement("SPAN")
  380.         oChild.appendChild .createTextNode(" ")
  381.     End With
  382.     With oParent
  383.         .className = CL_INFOSPAN
  384.         .Style.visibility = "hidden"
  385.         .appendChild(oChild).className = "idSPAN"
  386.         .appendChild(oChild.cloneNode(True)).className = "mshtmlSPAN"
  387.     End With
  388.     Set Result = oParent
  389. CreatePropsClone_Exit:
  390.     Set CreatePropsClone = Result
  391.     Exit Function
  392. CreatePropsClone_Error:
  393.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "CreatePropsClone"
  394.     Resume CreatePropsClone_Exit
  395. End Function
  396. Private Sub DisplayStyleSheets(HTMLDoc As MSHTML.HTMLDocument)
  397.             
  398.     On Error GoTo DisplayStyleSheets_Error
  399.     Dim oRules As MSHTML.HTMLStyleSheetRulesCollection
  400.     Dim varStyles() As String
  401.     Dim varStyle As Variant
  402.     Dim IXStyleSheet As Long
  403.     Dim IX As Long
  404.     Dim oLIparent As MSHTML.HTMLLIElement
  405.     Dim strSelectorText As String
  406. ' Create RootNode (fully constructed before added to document)
  407.     Set mULRoot = mWbrDoc.createElement("UL")
  408.     For IXStyleSheet = 0 To HTMLDoc.styleSheets.length - 1
  409.         Set oRules = HTMLDoc.styleSheets(IXStyleSheet).rules
  410.         For IX = 0 To oRules.length - 1
  411.             With oRules(IX)
  412.                 varStyles = Split(.Style.cssText, ";")
  413.                 strSelectorText = .selectorText
  414.                 With mULRoot.appendChild(mWbrDoc.createElement("LI"))
  415.                     .className = CL_PARENT
  416.                     .appendChild mWbrDoc.createTextNode(strSelectorText)
  417.                 End With
  418.                 With mULRoot.appendChild(mWbrDoc.createElement("UL"))
  419.                     .className = CL_CHILD
  420.                     For Each varStyle In varStyles
  421.                         With .appendChild(mWbrDoc.createElement("LI"))
  422.                             .appendChild mWbrDoc.createTextNode(varStyle)
  423.                         End With
  424.                     Next
  425.                 End With
  426.             End With
  427.         Next IX
  428.     Next IXStyleSheet
  429. ' Insert the UL Object into the document (in place of 'Working...')
  430.     With mWbrDoc.getElementById("MainDIV")
  431.         .replaceChild newChild:=mULRoot, oldChild:=.firstChild
  432.     End With
  433. ' Make clickable option available and monitor for click
  434.     Set mExpand = mWbrDoc.getElementById("idExpand")
  435.     mExpand.runtimeStyle.visibility = "visible"
  436. DisplayStyleSheets_Exit:
  437.     Exit Sub
  438. DisplayStyleSheets_Error:
  439.     MsgBox Err.Number & " - " & Err.Description, vbExclamation, "DisplayStyleSheets"
  440.     Resume DisplayStyleSheets_Exit
  441. End Sub
  442.